﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using Microsoft.Win32.TaskScheduler;
namespace PQRefreshScheduler
{
    public partial class PQRefreshScheduler : Form
    {


        #region Class Level Variables
        static string strFilePath = string.Empty;

        public delegate void DelegateAddString(String s);
        public delegate void DelegateThreadFinished();
        static DateTime dtSchedule;
        static DateTime dtSelectedTime;
        static double dbInterval;
        string PQFileName = string.Empty;
        string PQFilePath = string.Empty;
        string rootPath = string.Empty;
        bool IsDateSelected = false;
        bool IsTimeSelected = false;

        // worker thread
        Thread m_WorkerThread;

        // events used to stop worker thread
        ManualResetEvent m_EventStopThread;
        ManualResetEvent m_EventThreadStopped;

        // Delegate instances used to call user interface functions from worker thread:
        public DelegateAddString m_DelegateAddString;
        public DelegateThreadFinished m_DelegateThreadFinished;
        TaskService ts = new TaskService();


        #endregion

        #region Constructor

        public PQRefreshScheduler()
        {
            InitializeComponent();

            gbSchedule.Enabled = false;
            
            rootPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\PQRefresh";
            GetTaskHistory();
            m_EventStopThread = new ManualResetEvent(false);
            m_EventThreadStopped = new ManualResetEvent(false);
            groupBox1.TabStop = true;
        }

        #endregion

        #region Events

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog op = new OpenFileDialog();

            if (op.ShowDialog() == DialogResult.OK)
            {
                strFilePath = op.FileName;
                txtFilePath.Text = strFilePath;
                               
            }
        }

        private void btnGo_Click(object sender, EventArgs e)
        {
            try
            {
                if (txtFilePath.Text.Equals(string.Empty))
                {
                    MessageBox.Show("Please select a file for Refresh", "Select File", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (!txtInterval.Text.Equals(string.Empty))
                {
                    dbInterval = Convert.ToDouble(txtInterval.Text);
                }
                if(rbtnSchedule.Checked == false && rbtnRefreshNow.Checked == false)
                {
                    MessageBox.Show("Please select Refresh Now /Schedule", "Refresh", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                
                if (rbtnSchedule.Checked == true)
                {
                    if (txtName.Text.Equals(string.Empty))
                    {
                        MessageBox.Show("Please enter a name for Task to be created", "Task Name", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    if (txtInterval.Text.Equals(string.Empty))
                    {
                        MessageBox.Show("Please enter Repeat Interval for Task to be created in minutes", "Repeat Interval", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    if(Convert.ToInt32(txtInterval.Text).Equals(0))
                    {
                        MessageBox.Show("Repeat Interval should be greather than Zero", "Repeat Interval", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }

                #region Create Folder

                rootPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\PQRefresh";
                
                bool exists = System.IO.Directory.Exists(rootPath);

                if (!exists)
                    System.IO.Directory.CreateDirectory(rootPath);

                if (txtName.Text.Equals(string.Empty))
                {

                    PQFileName = "PQRefreshNowTest.vbs";
                }
                else
                {
                    PQFileName = txtName.Text + ".vbs";
                }

                PQFilePath = rootPath + "\\" + PQFileName;

                if (File.Exists(PQFilePath) && rbtnSchedule.Checked == true)
                {
                    DialogResult dr = MessageBox.Show("There is a Task Scheduled for this already! Do you want to over write it ?", "Task", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (dr.Equals(DialogResult.No))
                    {
                        return;
                    }

                }
                #endregion

                // reset events
                m_EventStopThread.Reset();
                m_EventThreadStopped.Reset();
                m_WorkerThread = new Thread(new ThreadStart(this.UpdateScriptFile));
                m_WorkerThread.Name = "Worker Thread ";
                m_WorkerThread.Start();
            }
            finally
            {
               
            }
        }


        private void dtpStart_ValueChanged(object sender, EventArgs e)
        {
            IsDateSelected = true;
            if (dtpStart.Value != null)
            {
                dtSchedule = dtpStart.Value;
            }

        }

        private void rbtnRefreshNow_CheckedChanged(object sender, EventArgs e)
        {
            if (rbtnRefreshNow.Checked == true)
            {
                gbSchedule.Enabled = false;
            }
        }

        private void rbtnSchedule_CheckedChanged(object sender, EventArgs e)
        {
            if (rbtnSchedule.Checked == true)
            {
                gbSchedule.Enabled = true;
            }

        }

        private void rbtnImmediate_CheckedChanged(object sender, EventArgs e)
        {
            //if (rbtnImmediate.Checked == true)
            //{
            //    dtpStart.Enabled = false;
            //}
        }

        private void rbtnDate_CheckedChanged(object sender, EventArgs e)
        {
            //if (rbtnDate.Checked == true)
            //{
            //    dtpStart.Enabled = true;
            //}

        }

        private void dtTime_ValueChanged(object sender, EventArgs e)
        {
            IsTimeSelected = true;
            if (dtTime.Value != null)
            {
                dtSelectedTime = dtTime.Value;
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                ts = new TaskService();
               
                foreach (var item in lvTasks.CheckedItems.OfType<ListViewItem>().ToList())
                {
                    ts.RootFolder.DeleteTask(item.Text.ToString());
                    lvTasks.Items.Remove(item);

                    if (PQFilePath.Equals(string.Empty))
                    {
                        PQFilePath = rootPath + "\\" + item.Text.ToString() + ".vbs";
                    }
                    File.Delete(PQFilePath);
                }
            }
            finally
            {

            }
        }

        private void btnTaskRefresh_Click(object sender, EventArgs e)
        {

        }

        private void clbTasks_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void lbTaskStatus_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void PQRefreshScheduler_Load(object sender, EventArgs e)
        {

        }

        #endregion

        #region Methods

        /// <summary>
        /// Update the RichTextBox for user display
        /// </summary>
        /// <param name="str"></param>
        public void UpdateRTB(string str)
        {
            if (str.Equals(string.Empty))
            {
                rtbProgress.Text = "No Duplicate Records found in this file";
            }
            else
            {
                rtbProgress.Text = str;
            }

           
        }

        /// <summary>
        /// Create Task
        /// </summary>
        /// <param name="path"></param>
        private void CreateTaskRunRepeatly(string path)
        {


            using (ts = new TaskService())
            {
                TaskDefinition td = ts.NewTask();
                TimeTrigger trigger = new TimeTrigger();
                DateTime dtScheduleDT;

                if(!txtName.Text.Equals(string.Empty))
                {
                    td.RegistrationInfo.Description = txtName.Text;
                }
                else
                {
                    td.RegistrationInfo.Description = "PBI Task1";
                }

                if (dtSchedule.Year.Equals(1))
                {
                    if(IsTimeSelected)
                    {
                        dtScheduleDT = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, dtSelectedTime.Hour, dtSelectedTime.Minute, dtSelectedTime.Second);
                        trigger.StartBoundary = dtScheduleDT;
                    }
                    else
                    {
                        trigger.StartBoundary = DateTime.Now;
                    }
                   
                    
                }
                else
                {
                    if (IsTimeSelected)
                    {
                        dtScheduleDT = new DateTime(dtSchedule.Year, dtSchedule.Month, dtSchedule.Day, dtSelectedTime.Hour, dtSelectedTime.Minute, dtSelectedTime.Second);
                        trigger.StartBoundary = dtScheduleDT;
                    }
                    else
                    {
                        dtScheduleDT = new DateTime(dtSchedule.Year, dtSchedule.Month, dtSchedule.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
                        trigger.StartBoundary = dtScheduleDT;
                    }
                }

                if(!txtInterval.Text.Equals(string.Empty))
                {
                    trigger.Repetition.Interval = TimeSpan.FromMinutes(dbInterval);
                }
                else
                {
                    trigger.Repetition.Interval = TimeSpan.FromMinutes(0);
                }
                
               // tc[i].Definition.RegistrationInfo.Author

                td.RegistrationInfo.Author = "PQRefreshScheduler";
                td.Triggers.Add(trigger);

                td.Actions.Add(new ExecAction(@"C:\Windows\System32\cscript.exe", "\"" + PQFileName + "\"", rootPath  +"\\"));

               // td.Actions.Add(new ExecAction(@"wscript.exe", "//B //nologo " + rootPath + "\\" + PQFileName  +  " /" + "TYPE:SU"));

                td.Settings.DisallowStartIfOnBatteries = false;
                td.Settings.StopIfGoingOnBatteries = false;
                

                if (!txtName.Text.Equals(string.Empty))
                {
                    
                    ts.RootFolder.RegisterTaskDefinition(txtName.Text, td);
                }
                else
                {
                    ts.RootFolder.RegisterTaskDefinition("PBI Task1", td);
                }    
            }


          
            
            

        }

        /// <summary>
        /// Task History Scheduled by this Tool
        /// </summary>
        private void GetTaskHistory()
        {
           using( TaskService tasksvc = new TaskService())
           { 
            //Get Task Collection
            TaskCollection tc = tasksvc.RootFolder.GetTasks();           

            //Clear Items in History List View
            if (tc != null)
            {
                if (tc.Count >= 0)
                {
                    if (lvTasks.Items.Count > 0)
                    {
                        Invoke(new System.Action(() => lvTasks.Items.Clear()));
                    }
                }
            }

            #region Add Tasks to History ListView

            ListViewItem lvi = new ListViewItem();
            string str;
            for (int i = 0; i < tc.Count; i++)
            {
                if (tc[i].Definition.RegistrationInfo.Author != null)
                {
                    if (tc[i].Definition.RegistrationInfo.Author.Equals("PQRefreshScheduler"))
                    {
                        
                    if (!lvTasks.InvokeRequired)
                    {
                        lvi = new ListViewItem(tc[i].Name);

                        lvi.SubItems.Add(tc[i].State.ToString());

                        if (tc[i].LastRunTime.Year.Equals(1))
                        {
                            lvi.SubItems.Add(" ");
                        }
                        else
                        {
                            lvi.SubItems.Add(tc[i].LastRunTime.ToString());
                        }
                      
                        if (tc[i].LastTaskResult.Equals(0))
                        {
                            lvi.SubItems.Add("Success");
                        }
                        else if (tc[i].LastTaskResult.Equals(1))
                        {
                            if (tc[i].LastRunTime.Year.Equals(1))
                            {
                                lvi.SubItems.Add("Never");
                            }
                            else
                            {
                                lvi.SubItems.Add("Failed");
                            }
                        }
                        else
                        {
                            lvi.SubItems.Add("       ");
                        }


                        lvi.SubItems.Add(tc[i].Definition.Triggers.ToString());

                        

                        lvTasks.Items.Add(lvi);
                    }
                    else
                    {
                        


                        Invoke(new System.Action(() => lvi = new ListViewItem(tc[i].Name)));
                        Invoke(new System.Action(() => lvi.SubItems.Add(tc[i].State.ToString())));

                        if (tc[i].LastRunTime.Year.Equals(1))
                        {
                            Invoke(new System.Action(() => lvi.SubItems.Add("        ")));
                        }
                        else
                        {
                            Invoke(new System.Action(() => lvi.SubItems.Add(tc[i].LastRunTime.ToString())));
                        }

                        

                        if (tc[i].LastTaskResult.Equals(0))
                        {
                            Invoke(new System.Action(() => lvi.SubItems.Add("Success")));
                        }
                        else if (tc[i].LastTaskResult.Equals(1))
                        {
                            
                            if (tc[i].LastRunTime.Year.Equals(1))
                            {
                                Invoke(new System.Action(() => lvi.SubItems.Add("Never")));
                            }
                            else
                            {
                                Invoke(new System.Action(() => lvi.SubItems.Add("Failed")));
                            }
                        }
                        else
                        {
                            Invoke(new System.Action(() => lvi.SubItems.Add("        ")));
                        }

                        str = tc[i].Definition.Triggers.ToString();
                        Invoke(new System.Action(() => lvi.SubItems.Add(str)));



                        Invoke(new System.Action(() => lvTasks.Items.Add(lvi)));
                        
                    }

                }
                }

            }
            #endregion

           }
        }

        /// <summary>
        /// Update Script file to use in Tasks
        /// </summary>
        public void UpdateScriptFile()
        {
           
            try
            {

                
                string exe_path = (new FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location)).DirectoryName;
                string text = exe_path + "\\PQ_Refresh.vbs";
                //int line = File.ReadAllLines(text).Length;
                String strLine;
                StringBuilder sb = new StringBuilder();

                using (var sr = new StreamReader(text))
                {
                    //for (int i = 1; i < line; i++)
                    foreach (string s in File.ReadAllLines(text))
                    {
                        strLine = sr.ReadLine();
                        if (!strLine.Contains("objExcel.Workbooks.Open(\""))
                        {
                            sb.AppendLine(strLine);

                        }
                        else
                        {
                            sb.Append("objExcel.Workbooks.Open(\"" + strFilePath + "\") ' Path to Excel Spreadsheet");
                            sb.AppendLine();
                        }

                    }

                }

                if (PQFilePath.Equals(".vbs"))
                    PQFilePath = "PQRefreshNowTest.vbs";

                File.WriteAllText(PQFilePath, sb.ToString());

                #region execute VB Script
                if (rbtnRefreshNow.Checked == true)
                {
                    Process scriptProc = new Process();
                    scriptProc.StartInfo.FileName = @"cscript";
                    scriptProc.StartInfo.Arguments = "\"" + PQFilePath + "\"";
                    scriptProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    scriptProc.Start();
                    scriptProc.WaitForExit();
                    scriptProc.Close();
                }
                else if(rbtnSchedule.Checked == true)
                {
                    CreateTaskRunRepeatly(text);
                }
                #endregion
                GetTaskHistory();


                #region Scrap


                #endregion


            }
            catch (Exception ex)
            {

            }
        }

        private void ValidateFilePathNValues()
        {

        }

        #endregion

        private void txtInterval_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = (!char.IsDigit(e.KeyChar)) && (!char.IsControl(e.KeyChar));
        }

        
    }
}
